LBB: IMDb Data Visualization


1. Pendahuluan

library(tidyverse)
library(ggpubr)
library(scales)
library(glue)
library(plotly)
library(lubridate)
library(ggplot2)
library(rAmCharts)
library(scales)
library(dplyr)

Pada LBB (Learning by Building) ini akan dilakukan Data Visualization menggunakan dataset IMDb. IMDb (Internet Movie Database) adalah sebuah basis data daring informasi yang berkaitan dengan film, acara televisi, video rumahan, dan permainan video, dan acara internet, termasuk daftar pemeran, biografi kru produksi dan personil, ringkasan alur cerita, trivia, dan ulasan serta penilaian oleh penggemar. Sebuah fitur penggemar tambahan, papan pesan, telah dinonaktifkan pada Februari 2017. Awalnya situs ini dioperasikan oleh penggemar, lalu basis data kemudian dimiliki dan dioperasikan oleh IMDB.com Inc., sebuah anak perusahaan dari Amazon.

2. Mengimport Data

Hal paling pertama yang harus dilakukan adalah pastikan lokasi folder dataset yang ingin diinput sama dengan Rmd ini. Kemudian, lanjut dengan read dataset. File dataset yang digunakan yaitu imdb.csv.

imdb <- read.csv("imdb.csv", stringsAsFactors = T)

Dataset telah terbaca dan terinput dengan nama imdb. Untuk mengetahui isi dataset tersebut, lakukan ke tahap selanjutnya yaitu dengan cara menginspeksi data.

3. Menginspeksi Data

head(imdb)
dim (imdb)
#> [1] 6178   14

Terlihat bahwa data terdiri dari 6178 baris dan 14 kolom. Kemudian, cek missing value apakah ada atau tidak

anyNA(imdb)
#> [1] FALSE
colSums(is.na(imdb))
#>        Name        Date        Rate       Votes       Genre    Duration 
#>           0           0           0           0           0           0 
#>        Type Certificate    Episodes      Nudity    Violence   Profanity 
#>           0           0           0           0           0           0 
#>     Alcohol Frightening 
#>           0           0

Terlihat bahwa tidak ada missing value, sehingga data siap diolah ke tahap selanjutnya.

4. Mengolah Data

summary(imdb)
#>             Name           Date           Rate           Votes     
#>  King Kong    :   5   Min.   :1922   7.3    : 273   No Votes: 185  
#>  Cat People   :   4   1st Qu.:1998   7.2    : 235   132     :   5  
#>  Flatliners   :   4   Median :2011   7.1    : 227   2,458   :   4  
#>  Get Shorty   :   4   Mean   :2006   7.6    : 226   20,377  :   4  
#>  Little Women :   4   3rd Qu.:2019   6.8    : 225   21,413  :   4  
#>  Lost in Space:   4   Max.   :2023   6.6    : 224   25,963  :   4  
#>  (Other)      :6153                  (Other):4768   (Other) :5972  
#>                    Genre         Duration        Type       Certificate  
#>  Comedy               : 268   60     : 352   Film  :4446   R      :1885  
#>  Drama                : 259   None   : 301   Series:1732   PG-13  :1147  
#>  Crime, Drama, Mystery: 220   30     : 246                 TV-MA  : 641  
#>  Comedy, Drama        : 199   97     : 122                 TV-14  : 575  
#>  Drama, Romance       : 189   100    : 117                 PG     : 530  
#>  Action, Crime, Drama : 171   90     : 117                 None   : 450  
#>  (Other)              :4872   (Other):4923                 (Other): 950  
#>     Episodes         Nudity         Violence       Profanity        Alcohol    
#>  -      :4446   Mild    :2292   Mild    :1703   Mild    :2077   Mild    :3257  
#>  10     :  82   Moderate:1251   Moderate:1814   Moderate:1646   Moderate:1051  
#>  20     :  65   No Rate : 707   No Rate : 759   No Rate : 745   No Rate : 812  
#>  16     :  53   None    :1459   None    : 674   None    : 658   None    : 771  
#>  12     :  49   Severe  : 469   Severe  :1228   Severe  :1052   Severe  : 287  
#>  8      :  46                                                                  
#>  (Other):1437                                                                  
#>    Frightening  
#>  Mild    :1587  
#>  Moderate:1969  
#>  No Rate : 858  
#>  None    : 858  
#>  Severe  : 906  
#>                 
#> 

Dari summary tersebut, dapat diperoleh beberapa informasi:

  1. Terdapat lebih dari 6000 judul yang terdapat di dataset imdb.
  2. Adanya Rate memungkinkan untuk mengurutkan data dari Rating tertinggi sampai terendah.
  3. Ada dua tipe jenis tontonan yang dinilai oleh imdb yaitu tipe film dan tipe series.
  4. Film/series tersebut diproduksi dari tahun 1922 sampai dengan tahun 2023 (perkiraan).
  5. Terdapat sangat banyak jenis genre dari film/series tersebut, sehingga susah untuk diklasifikasikan secara rinci.
  6. Film/series tersebut mengandung unsur: Nudity, Violence, Profanity, Alcohol dan Frightening yang masing - masingnya mempunyai level: Mild, Moderate, No Rate, None dan Severe.

Setelah mengetahui beberapa informasi yang diperoleh dari summary tersebut, diperoleh ide visualization apa yang akan dibuat. Sebelum membuat visualization, diperlukan pengolahan data agar proses pembuatan visualization bekerja dengan baik dan benar. Pertama, cek tipe data dari setiap kolom dataset imdb

str(imdb)
#> 'data.frame':    6178 obs. of  14 variables:
#>  $ Name       : Factor w/ 4820 levels "'Allo 'Allo!",..: 2569 3861 4042 4589 1113 3497 1362 1736 4679 3148 ...
#>  $ Date       : int  2021 2021 2021 2021 2021 2021 2021 2021 2021 2021 ...
#>  $ Rate       : Factor w/ 77 levels "1.2","1.9","2.0",..: 55 42 43 43 62 67 52 77 55 62 ...
#>  $ Votes      : Factor w/ 4802 levels "1,000","1,015",..: 308 3927 2187 2444 4486 480 1024 4802 3495 1800 ...
#>  $ Genre      : Factor w/ 377 levels "Action","Action, Adventure",..: 14 236 225 13 6 177 4 6 113 167 ...
#>  $ Duration   : Factor w/ 203 levels "100 ","101 ",..: 70 192 23 200 61 126 17 203 203 143 ...
#>  $ Type       : Factor w/ 2 levels "Film","Series": 1 1 1 1 1 2 1 2 2 2 ...
#>  $ Certificate: Factor w/ 23 levels "(Banned)","Approved",..: 13 14 14 13 13 17 13 9 15 17 ...
#>  $ Episodes   : Factor w/ 284 levels "-","10","100",..: 1 1 1 1 1 131 1 2 92 145 ...
#>  $ Nudity     : Factor w/ 5 levels "Mild","Moderate",..: 1 4 2 4 4 1 1 3 4 5 ...
#>  $ Violence   : Factor w/ 5 levels "Mild","Moderate",..: 2 4 5 2 2 4 2 3 2 1 ...
#>  $ Profanity  : Factor w/ 5 levels "Mild","Moderate",..: 1 5 5 2 4 5 2 3 1 5 ...
#>  $ Alcohol    : Factor w/ 5 levels "Mild","Moderate",..: 1 4 2 1 1 1 4 3 1 2 ...
#>  $ Frightening: Factor w/ 5 levels "Mild","Moderate",..: 2 2 2 2 2 4 1 3 2 1 ...

Ternyata diperlukan deselect beberapa kolom karena tidak diperlukan, menghapus koma pada isi kolom Votes dan mengubah tipe data beberapa kolom. Proses tersebut disebut cleansing data, hasil pengolahan data disimpan dengan nama imdb_clean.

# Cleansing Data
imdb_clean <- imdb %>% 
  select(-c(Duration,Certificate,Episodes)) %>% # deselect beberapa kolom
  mutate(
    Name = as.character(Name),# mengubah tipe data
    Rate = as.numeric(as.character(Rate)),
    Votes = as.numeric(gsub(",","",Votes)),
    Genre = as.character(Genre),
    Nudity = as.character(Nudity),
    Violence = as.character(Violence),
    Profanity = as.character(Profanity),
    Alcohol = as.character(Alcohol),
    Frightening = as.character(Frightening),
    Type = as.character(Type)
  )

Ternyata menghasilkan Warning yaitu adanya NA. Untuk lebih akuratnya, cek NA pada dataset imdb_clean tersebut

anyNA(imdb_clean)
#> [1] TRUE
colSums(is.na(imdb_clean))
#>        Name        Date        Rate       Votes       Genre        Type 
#>           0           0         185         185           0           0 
#>      Nudity    Violence   Profanity     Alcohol Frightening 
#>           0           0           0           0           0

Ternyata benar, terdapat nilai NA di kolom Rate dan Votes. Untuk mengatasinya, ubah nilai NA menjadi 0

imdb_clean[is.na(imdb_clean)] = 0

Cek kembali apakah masih terdapat NA

anyNA(imdb_clean)
#> [1] FALSE

Terlihat bahwa tidak ada NA lagi, sehingga data siap diolah ke tahap selanjutnya yaitu data wrangling

# Data Wrangling

# Case 1
imdb_count_type <- imdb_clean %>% 
  group_by(Type) %>% 
  summarise(count=n()) %>% 
  ungroup() %>% 
  arrange(-count)

# Case 2
imdb_10films <- imdb_clean %>% 
  filter(Type==imdb_count_type$Type[1]) %>% # filter untuk film
  group_by(Name) %>% 
  summarise(mean_rate=mean(Rate)) %>% 
  ungroup() %>% 
  arrange(-mean_rate) %>% 
  top_n(10)

# Case 3
imdb_10series <- imdb_clean %>% 
  filter(Type==imdb_count_type$Type[2]) %>% # filter untuk series
  group_by(Name) %>% 
  summarise(mean_rate=mean(Rate)) %>% 
  ungroup() %>% 
  arrange(-mean_rate) %>% 
  top_n(10)

# Case 4
imdb_year <- imdb_clean %>% 
  group_by(Date) %>% 
  summarise(count=n()) %>% 
  ungroup() %>% 
  arrange(-count)

# Case 5
imdb_count_nudity <- imdb_clean %>% 
  group_by(Nudity) %>% 
  summarise(count=n()) %>% 
  ungroup() %>% 
  arrange(-count)

5. Membuat Plot

PLOT 1

Visualisasi persentasi banyaknya data film dan series:

plot1 <- amPie(data.frame(label = as.factor(names(table(imdb_clean$Type))), value = as.vector(table(imdb_clean$Type))), main = "Percentage Data of Films and Series",mainColor="black",theme="light")
plot1

Dari visualisasi di atas diperoleh bahwa persentase data film itu lebih banyak yaitu 71.97% atau 4446 data, dan persentase data series 28.03% atau 1732 data.

PLOT 2

Visualisasi judul film berdasarkan rating teratas:

imdb_films <- imdb_10films %>% 
  mutate(label=glue("Name: {Name}
                    Average Views: {comma(mean_rate)}"))

plot2 <- ggplot(imdb_films, aes(x = reorder(Name, mean_rate), 
                    y = mean_rate,
                    text = label)) +
  geom_segment(aes(x=reorder(Name, mean_rate), xend=reorder(Name, mean_rate), y=0,yend=mean_rate), color="red") +
  geom_point(color="black") +
  coord_flip() +
  labs(title = "TOP FILMS RATING",
       x = NULL,
       y = "Average Rate") +
  scale_y_continuous(labels = comma) +
  theme_minimal()

ggplotly(plot2, tooltip = "text")

Dari visualisasi di atas diperoleh bahwa judul film yang menduduki rating teratas yaitu Toma dan The Shawshank Redemption mempunyai rating yang sama yaitu 9.3 kemudian disusul oleh film The Godfather dengan rating 9.2, dsb

PLOT 3

Visualisasi judul series berdasarkan rating teratas:

imdb_series <- imdb_10series %>% 
  mutate(label=glue("Name: {Name}
                    Average Views: {comma(mean_rate)}"))

plot3 <- ggplot(imdb_series, aes(x = reorder(Name, mean_rate), 
                    y = mean_rate,
                    text = label)) +
  geom_segment(aes(x=reorder(Name, mean_rate), xend=reorder(Name, mean_rate), y=0,yend=mean_rate), color="red") +
  geom_point(color="black") +
  coord_flip() +
  labs(title = "TOP 10 SERIES RATING",
       x = NULL,
       y = "Average Rate") +
  scale_y_continuous(labels = comma) +
  theme_minimal()

ggplotly(plot3, tooltip = "text")

Dari visualisasi di atas diperoleh bahwa judul series yang menduduki rating teratas yaitu Aspirants dengan rating 9.7 kemudian disusul oleh The Chosen dan Bluey yang mempunyai rating yang sama yaitu 9.6, dsb

PLOT 4

Visualisasi judul film/series berdasarkan tahun:

imdb_count <- imdb_year %>% 
  mutate(label = glue(
    "Year: {Date}
    Count: {count}"
  ))

plot4 <- ggplot(imdb_count, aes(x=Date, y= count))+
  geom_line(col="red") +
  geom_point(aes(text=label), col="black") +
  labs(
  title = glue("Years of Film/Series Production"),
  x = "Years",
  y = "Count"
  ) +
  theme_minimal()

ggplotly(plot4, tooltip = "text")

Dari visualisasi di atas diperoleh bahwa tahun produksi yang menghasilkan film/series paling banyak yaitu 2021 yaitu sebanyak 736 data dan yang paling sedikit yaitu tahun 1922 yaitu 1 data.

PLOT 5

Dari unsur yang terdapat pada setiap film/series, disini hanya akan dibuat plot berdasarkan unsur Nudity Level saja

imdb_count2 <- imdb_count_nudity %>% 
  mutate(label = glue(
    "Nudity: {Nudity}
    Count: {count}"
  ))
plot5 <- ggplot(data = imdb_count2, aes(x = count, 
                              y = reorder(Nudity, count), # reorder(A, berdasarkan B)
                              text = label)) + 
  geom_col(aes(fill = count)) +
  labs(title = "NUDITY LEVEL",
       x = "Count",
       y = NULL) +
  theme_minimal() +
  theme(legend.position = "none") 

ggplotly(plot5, tooltip = "text")

Dari visualisasi di atas diperoleh bahwa Nudity Level yang paling tinggi adalah level Mild dan yang paling rendah adalah level Severe.